package datasorters;

import org.apache.log4j.Logger;

import java.util.Random;

public class BogoSort {
    private static final Logger l = Logger.getLogger(BogoSort.class);
    private static Random random = new Random();
    private static int timeUsed = 0;

    private static void reverse(Integer[] data) {
        for (int i = 0; i < data.length / 2; i++) {
            int temp = data[i];
            data[i] = data[data.length - 1 - i];
            data[data.length - 1 - i] = temp;
        }
    }

    private void sortAsc(Integer[] data) {
        while (!inOrder(data)) {
            shuffle(data);
        }
    }

    private void shuffle(Integer[] data) {
        for (int i = 0; i < data.length; i++) {
            int swapPosition = random.nextInt(i + 1);
            int temp = data[i];
            data[i] = data[swapPosition];
            data[swapPosition] = temp;
            timeUsed += 3;
        }
    }

    private boolean inOrder(Integer[] data) {
        for (int i = 0; i < data.length - 1; i++) {
            timeUsed++;
            if (data[i] > data[i + 1]) {
                return false;
            }
        }
        return true;
    }

    public Integer[] sort(Integer[] data) {
        if (data == null)
            return null;
        if (data.length == 0)
            return data;

        Integer[] sortedData = new Integer[data.length];
        System.arraycopy(data, 0, sortedData, 0, data.length);

        sortAsc(sortedData);

        int f = 1;
        for (int i = 2; i <= data.length; i++) {
            f *= i;
        }
        int expectedTime = data.length * f;
        l.info("Time used: " + timeUsed + ". Expected time: N*N! = " + expectedTime);

        return sortedData;
    }

    public Integer[] sort(Integer[] data, SortType type) {
        Integer[] sortedData = sort(data);
        if (SortType.DESC.equals(type))
            reverse(sortedData);
        return sortedData;
    }
}
